package com.qq.weixin.mp.api.pay.impl;

import java.io.IOException;
import java.io.StringReader;
import java.nio.charset.UnsupportedCharsetException;

import javax.xml.bind.JAXBException;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.hxexp.weixin.common.exception.APIException;
import com.hxexp.weixin.common.httpclient.StringResponseHandler;
import com.hxexp.weixin.common.jaxb.JaxbMarshallerHelper;
import com.hxexp.weixin.common.jaxb.JaxbUnmarshallerHelper;
import com.qq.weixin.mp.api.pay.PayAPI;
import com.qq.weixin.mp.api.pay.model.PayCommonJaxb;
import com.qq.weixin.mp.api.pay.model.UnifiedOrderJaxb;
import com.qq.weixin.mp.api.pay.model.UnifiedOrderParamJaxb;

/**
 * 微信支付API接口实现类
 * @author li.jiang
 *
 */
@Component
public final class PayAPIImpl implements PayAPI {
    private final CloseableHttpClient httpclient = HttpClients.createDefault();
    @Value("${pay_api.unifiedorder.url}")
    private String unifiedorderApiUrl;
    /* (non-Javadoc)
     * @see com.hxexp.weixin.api.pay.wrapper.PayAPI#UnifiedOrderAPI(com.hxexp.weixin.model.apiparam.pay.UnifiedOrderParamJaxb)
     */
    @Override
    public UnifiedOrderJaxb unifiedOrderAPI(final UnifiedOrderParamJaxb paramJaxb) throws APIException {
        HttpPost post = new HttpPost(unifiedorderApiUrl);

        try {
            String postData = JaxbMarshallerHelper.marshalToString(paramJaxb);

            StringEntity entity = new StringEntity(postData, ContentType.create("text/xml", "utf-8"));
            post.setEntity(entity);

            // 使用自定义的StringResponseHandler解决返回的响应字符串中文乱码问题
            String xmlResult = httpclient.execute(post, new StringResponseHandler());

            return (UnifiedOrderJaxb) JaxbUnmarshallerHelper.unmarshal(new StringReader(xmlResult),
                    new Class<?>[] { PayCommonJaxb.class, UnifiedOrderJaxb.class });
        } catch (UnsupportedCharsetException e) {
            throw new APIException(e);
        } catch (ClientProtocolException e) {
            throw new APIException(e);
        } catch (JAXBException e) {
            throw new APIException(e);
        } catch (IOException e) {
            throw new APIException(e);
        }
    }

}
